/**
一定要记得在confin.json配置这个模块的参数,否则无法使用
*/
package game

import (
	"github.com/liangdas/mqant/conf"
	"github.com/liangdas/mqant/gate"
	"github.com/liangdas/mqant/module"
	"github.com/liangdas/mqant/module/base"
	"model/game"
	"model"
	"utils"
	"strconv"
	"fmt"
	"time"
	"model/config"
	"model/gamelog"
)

var Layout = "2006-01-02 15:04:05"
var Module = func() module.Module {
	game := new(Game)
	return game
}
type Game struct {
	basemodule.BaseModule
}
func (m *Game) GetType() string {
	//很关键,需要与配置文件中的Module配置对应
	return "Game"
}
func (m *Game) Version() string {
	//可以在监控时了解代码版本
	return "1.0.0"
}
func (m *Game) OnInit(app module.App, settings *conf.ModuleSettings) {
	//初始化模块
	m.BaseModule.OnInit(m, app, settings)
	//注册远程调用的函数
	m.GetServer().RegisterGO("HD_ShopList", m.shopList) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_PlantList", m.plantList) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_PlantAction", m.plantAction) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_WaterAction", m.waterAction) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_PlantDetail", m.plantDetail) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_UprootAction", m.uprootAction) //我们约定所有对客户端的请求都以Handler_开头
	m.GetServer().RegisterGO("HD_GainAction", m.gainAction) //我们约定所有对客户端的请求都以Handler_开头
}
func (m *Game) Run(closeSig chan bool) {
	//运行模块
}
func (m *Game) OnDestroy() {
	//注销模块
	//一定别忘了BaseModule.OnDestroy()
	m.BaseModule.OnDestroy()
}
//种植详情页面
func (m *Game) plantDetail(session gate.Session, msg map[string]interface{}) (result map[string]interface{}, err string) {
	fmt.Println(msg)
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	userId:=msg["userId"]
	areaId:=msg["areaId"]
	id:=msg["id"]
	where := map[string]interface{}{"userId": userId,"areaId": areaId,"id":id}
	var plant game.GamePlant
	var plantDetail game.PlantDetail
	selectStr:="growStage,curGrow"
	if err:=gameDb.Select(selectStr).Where(where).First(&plant).Scan(&plantDetail).Error;err!=nil{
		return nil,"没有相关信息"
	}
	result = utils.Struct2Map(plantDetail)
	return
}
func (m *Game) plantList(session gate.Session, msg map[string]interface{}) (result map[string]interface{}, err string) {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	userId := msg["userId"]
	areaId := msg["areaId"]
	if userId==nil{
		err = "userId未知"
		return nil,err
	}
	if areaId==nil{
		err = "areaId未知"
		return nil,err
	}
	var plants []game.GamePlant
	var results []game.PlantResult
	selectStr:="id,pId,pName,growStage,userId,selfWateringCount,otherWateringCount,curGrow,grow1,grow2,grow3,indexId,plantTime,lastOperateTime"
	where := map[string]interface{}{"userId": userId,"areaId": areaId}
	gameDb.Select(selectStr).Where(where).Limit(9).Find(&plants).Scan(&results)
	d := make(map[string]interface{}, len(results))
	for k,v:= range results{
		s := strconv.Itoa(k)
		d[s] = utils.Struct2Map(v)
	}
	ds := make(map[string]interface{}, len(results))
	ds["list"] = d
	return ds,""
}
//商品列表
func (m *Game) shopList(session gate.Session, msg map[string]interface{}) (result map[string]interface{}, err string) {
	fmt.Println(msg);
	var gameDb = model.DB("FarmGame")
	areaId := msg["areaId"]
	sType := msg["sType"]
	fmt.Printf("%+v",sType)
	fmt.Printf("%+v",areaId)
	if areaId==nil{
		err = "areaId未知"
		return nil,err
	}
	defer gameDb.Close()
	var results []game.ShopListResult
	var shops []game.GameShop
	sort:="id desc"
	var prepage int8=6
	var page int8=0
	where:=map[string]interface{}{"status": 1,"areaId":areaId,"sType":sType}
	selectStr:="id,propName,price,parPrice,info"
	ds:=utils.GetPageList(gameDb,&results,&shops,selectStr,where,sort,prepage,page,"game_shop",true)
	return ds,""
}
//当前地块是否可以使用
/*
	true:可以使用
	false:已被使用
*/
func (m *Game) isPlant(msg map[string]interface{}) bool{
	areaId := msg["areaId"]
	userId := msg["userId"]
	indexId := msg["indexId"]
	//dId := msg["dId"] //仓库种子id
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	var plants game.GamePlant
	where := map[string]interface{}{"userId": userId,"areaId": areaId,"indexId":indexId}
	rowNum := gameDb.Where(where).First(&plants).RowsAffected
	if rowNum > 0{
		return false
	}
	return true
}
//游戏操作
//种植行为条件判断  在哪块土块种植什么 是否有种子 土块是否可种植状态
func (m *Game) plantAction(session gate.Session, msg map[string]interface{}) (result bool, err string) {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	areaId := msg["areaId"].(float64)
	userId := msg["userId"].(float64)
	indexId := msg["indexId"].(float64) //土块Id
	fmt.Println(msg)
	if areaId<=0{
		err = "areaId未知"
		return false,err
	}
	if userId<=0{
		err = "userId未知"
		return false,err
	}
	mapArgs:=map[string]interface{}{"areaId":areaId,"userId":userId,"indexId":indexId}
	r1 := m.isPlant(mapArgs)
	//fmt.Println(r)
	if r1 == false{
		err = "土块被占用"
		return false,err
	}
	r2,err:= m.RpcInvoke("User", "isPossess", msg)
	if err!=""{
		fmt.Println(err)
		err = "种子不存在"
		return false,err
	}
	msg["sType"] = r2
	r3 := m.plantEvent(msg)
	if r3 == false{
		err = "种植失败"
		return false,err
	}
	return true,""
}
//种植事件 完成种植 消除仓库中种子信息 添加种植信息 添加种植事件日志
func (m *Game) plantEvent(msg map[string]interface{})(result bool) {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	pId := msg["pId"].(float64) //植物ID
	sType := msg["sType"].(float64) //植物ID
	areaId := msg["areaId"].(float64)
	userId := msg["userId"].(float64)
	indexId := msg["indexId"].(float64) //土块Id
	_pId:=uint(pId);
	_areaId:=uint(areaId)
	_growStage:="grow1"
	_userId:= uint(userId)
	_indexId:=int8(indexId)
	gc:=config.GetGrowcfg(_pId)
	_grow1 := gc.Grow1
	_grow2 := gc.Grow2
	_grow3 := gc.Grow3
	pName :=  gc.Name
	plants:=&game.GamePlant{
		PId:_pId,
		PName:pName,
		AreaId:_areaId,
		GrowStage:_growStage,
		UserId:_userId,
		PlantTime:time.Now(),
		LastOperateTime:time.Now(),
		SelfWateringCount:0,
		OtherWateringCount:0,
		CurGrow:0,
		Grow1:_grow1,
		Grow2:_grow2,
		Grow3:_grow3,
		IndexId:_indexId,
		SType:int8(sType),
	}
	where := map[string]interface{}{"userId": userId,"areaId": areaId,"indexId":indexId}
	if err:=gameDb.Where(where).Create(plants).Error;err!=nil{
		return false
	}else{
		r1,err:= m.RpcInvoke("User", "deleteSeed", msg)
		if err!=""{
			//panic(err)
		}
		if r1==false{
			gameDb.Delete(&plants)
			return false
		}else{
			//种植成功插入日志
			s := fmt.Sprintf("种植了一个[%s]", pName)
			f:=&gamelog.FarmPlantlog{
				AreaId:_areaId,
				UserId:_userId,
				ToUserId:_userId,
				LogMsg:s,
				LType:7,
				LaunchTime:time.Now(),
			}
			gamelog.AddPlantLog(f)
			return true
		}
	}
}
//次数浇水
/*自己浇水 判断该植物营养是否充分
          不充分/充分提示已充分
           判断自己的当天次数是否用完3次
			没用完/用完提示已用完
              执行浇水 植物养分+1 经验+1 浇水次数-1 当天浇水日志记录 累积次数+1
			ok
给别人浇水 判断该植物营养是否充分
          不充分/充分提示已充分
			判断好友庄园今日浇水次数是否到达上线
			没用完/到达上线提示已到达上线
			判断自己的当天给予好友总次数是否用完
			没用完/用完提示已用完
			判断自己今天给该好友浇水次数是否超过3次
			没超/超过提示超过
			执行浇水 植物养分+1 经验+1 浇水次数-1 当天操作日志记录  累积次数+1
			记录互动日志
*/

//浇水行为 是否可以浇水 使用什么浇水
func (m *Game) waterAction(session gate.Session, msg map[string]interface{})(result map[string]interface{},err string )  {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	var gamePlant game.GamePlant
	plantId := msg["plantId"] //种植ID
	areaId := msg["areaId"].(float64)
	toUserId := msg["toUserId"].(float64)
	userId := msg["userId"].(float64)
	wType := msg["wType"].(float64)
	var isSelf bool
	//获取事件接受者

	if toUserId == 0{
		isSelf = true
		toUserId = userId
	}else{
		isSelf = false
	}
	where:=map[string]interface{}{"userId": toUserId,"areaId":areaId,"id":plantId}
	if err:=gameDb.Where(where).First(&gamePlant).Error;err!=nil{
		return nil,"没有找到相关植物"
	}
	laststr:=gamePlant.LastOperateTime.Format("20060102")
	curstr:=time.Now().Format("20060102")
	if laststr != curstr{
		gameDb.Model(&gamePlant).Update(map[string]interface{}{"curGrow": 0, "selfWateringCount": 0,"otherWateringCount":0,"lastOperateTime":time.Now()})
	}

	//判断是否有浇水条件
	if wType==0{//使用能量浇水
		//扣除能量
		r1,err:= m.RpcInvoke("User", "useEnergy", msg)

		if r1==false{
			fmt.Println(r1)
			return map[string]interface{}{},err
		}else{
			gamePlant.CurGrow+=1
			gameDb.Save(&gamePlant)

		}
	}else{
		var waterCfg game.WaterCfg
		where:=map[string]interface{}{"userId": userId,"areaId":areaId}
		if err:=gameDb.Where(where).First(&waterCfg).Error;err!=nil{
			fmt.Println("创建")
			//没有记录  首次创建
			waterCfg := &game.WaterCfg{
				UserId:uint(userId),
				AreaId:uint(areaId),
				SelfCount:0,
				OtherCount:0,
				GiveCount:0,
				LogDate:time.Now(),
			}
			gameDb.Create(waterCfg)
		}
			//查询浇水次数信息
			//m1:=map[string]float64{"areaId":areaId,"userId":userId}
			//r1,err:= m.RpcInvoke("User", "waterChance", m1)
			//if err!=""{
			//	panic(err)
			//}
			//r1Map:=utils.IToMap(r1)
			//SelfCount:=r1Map["selfWater"].(float64)
			//otherMaxWater:=r1Map["otherWater"].(float64)
			//giveCount:=r1Map["giveCount"].(float64)
			//receiveCount:=r1Map["receiveCount"].(float64)

			//判断是否是当天的 不是就要update
			waterDate:=waterCfg.LogDate.Format("20060102")
			curDate:=time.Now().Format("20060102")

			if waterDate!=curDate{
				//update日期
				waterCfg.LogDate = time.Now()
				waterCfg.SelfCount = 0
				waterCfg.OtherCount = 0
				where:=map[string]interface{}{"userId":waterCfg.UserId}
				gameDb.Model(&waterCfg).Where(where).Update(map[string]interface{}{"selfCount": 0,"logDate":time.Now(),"otherCount":0})
			}
			//自己浇水
			if isSelf == true{
				//判断该植物营养是否充分
				if gamePlant.SelfWateringCount<3{
					//判断自己当天浇水次数 去water_cfg查
					if waterCfg.SelfCount<3{
						//不充分可以浇水
						gc:=gamePlant.CurGrow+1 //植物营养+1
						gs:=gamePlant.SelfWateringCount+1 //当前植物今日浇水次数+1
						//经验也要+1 待完成
						msg["exp"] = 1;
						_,err:= m.RpcInvoke("User", "updateExp", msg)
						if err!=""{
							//defer panic(err)
							return nil,"浇水失败"
						}
						gameDb.Model(&gamePlant).Update(map[string]interface{}{"curGrow": gc, "selfWateringCount": gs,"lastOperateTime":time.Now()})
						ws:=waterCfg.SelfCount +1 //今日自己浇水次数+1
						where:=map[string]interface{}{"userId": userId,"areaId":areaId}
						gameDb.Model(&waterCfg).Where(where).Update(map[string]interface{}{"selfCount": ws})
						//写操作日志
						//种植成功插入日志
						f:=&gamelog.FarmPlantlog{
							AreaId:uint(areaId),
							UserId:uint(userId),
							ToUserId:uint(toUserId),
							LogMsg:"浇水一次",
							LType:7,
							LaunchTime:time.Now(),
						}
						gamelog.AddPlantLog(f)

					}else{
						return nil,"您今天浇水次数到达上线"
					}

				}else{
					return nil,"该植物今天水量充分"
				}
			}else{

				//给好友浇水
				if gamePlant.OtherWateringCount<=3 {
					var waterCfg2 game.WaterCfg
					where:=map[string]interface{}{"userId": toUserId,"areaId":areaId}
					if err:=gameDb.Where(where).First(&waterCfg2).Error;err!=nil{
						//没有记录  首次创建
						waterCfg2 := &game.WaterCfg{
							UserId:uint(toUserId),
							AreaId:uint(areaId),
							SelfCount:0,
							OtherCount:0,
							GiveCount:0,
							LogDate:time.Now(),
						}
						gameDb.Create(waterCfg2)
					}
					//判断好友庄园今日浇水次数是否到达上线
					//查询浇水次数信息
					//m1:=map[string]float64{"areaId":areaId,"userId":userId}
					//r1,err:= m.RpcInvoke("User", "waterChance", m1)
					//if err!=""{
					//	panic(err)
					//}
					//r1Map:=utils.IToMap(r1)
					//SelfCount:=r1Map["selfWater"].(float64)
					//otherMaxWater:=r1Map["otherWater"].(float64)
					//giveCount:=r1Map["giveCount"].(float64)
					//receiveCount:=r1Map["receiveCount"].(float64)
					if waterCfg2.OtherCount<=15{
						//判断自己的当天给予好友总次数是否用完
						if waterCfg.GiveCount<=30{
							//判断自己今天给该好友浇水次数是否超过3次
							count:=gamelog.GetWaterNum(userId,toUserId)
							if count < 3{
								gc:=gamePlant.CurGrow+1 //植物营养+1
								gs:=gamePlant.OtherWateringCount+1
								//经验也要+1 待完成
								//经验也要+1 待完成
								msg["exp"] = 1;
								_,err:= m.RpcInvoke("User", "updateExp", msg)
								if err!=""{
									//defer panic(err)
									return nil,"浇水失败"
								}
								gameDb.Model(&gamePlant).Update(map[string]interface{}{"curGrow": gc, "otherWateringCount": gs,"lastOperateTime":time.Now()})
								ws:=waterCfg.OtherCount +1
								gameDb.Model(&waterCfg).Update(map[string]interface{}{"OtherCount": ws})
								//写操作日志
								//种植成功插入日志
								f:=&gamelog.FarmPlantlog{
									AreaId:uint(areaId),
									UserId:uint(userId),
									ToUserId:uint(toUserId),
									LogMsg:"浇水一次",
									LType:7,
									LaunchTime:time.Now(),
								}
								gamelog.AddPlantLog(f)

								//交互日志累计次数+1就可以
								//interact_log
								var logDb = model.DB("FarmLog")
								defer logDb.Close()
								var interact gamelog.InteractLog;
								where:=map[string]interface{}{"userId": toUserId,"areaId":areaId}
								if rows:=logDb.Where(where).First(&interact).RowsAffected;rows<=0{
									interactLog:=&gamelog.InteractLog{
										UserId:uint(userId),
										ToUserId:uint(toUserId),
										WaterCount:1,
										IType:0,
										LogTime:time.Now(),
										Msg:"浇水",
									}
									if err:=logDb.Create(&interactLog).Error;err!=nil{
										//defer panic(err)
									}
								}else{
									interact.LogTime = time.Now()
									WaterCount:=interact.WaterCount+1
									logDb.Save(&interact)
									logDb.Model(&interact).Update(map[string]interface{}{"waterCount": WaterCount})
								}
							}else{
								return nil,"给该好友浇水次数超过上线"
							}
						}else{

							return nil,"当天给予好友总次数已用完"

						}
					}else{
						return nil,"该庄园水量充分，不能再浇水，去看看其它好友庄园吧"
					}
				}else {
					return nil,"该植物今天水量充分"
				}
			}
		}
	result = map[string]interface{}{"GrowStage": gamePlant.GrowStage,"CurGrow":gamePlant.CurGrow}

	return result,""
}

//铲除
func (m *Game) uprootAction(session gate.Session, msg map[string]interface{}) (result float64, err string) {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	fmt.Println(msg)
	areaId := msg["areaId"].(float64)
	userId := msg["userId"].(float64)
	id := msg["id"].(float64)
	var plant game.GamePlant
	where:=map[string]interface{}{"userId": userId,"id":id,"areaId":areaId}
	if err:=gameDb.Where(where).First(&plant).Error;err!=nil{
		//defer panic(err)
		return 11,"植物不存在"
	}
	if err:=gameDb.Delete(&plant).Error;err!=nil{
		return 11,"铲除失败"
	}
	a:=float64(plant.IndexId)

	return a,""
}
//收获
func (m *Game) gainAction(session gate.Session, msg map[string]interface{}) (result bool, err string) {
	var gameDb = model.DB("FarmGame")
	defer gameDb.Close()
	fmt.Println(msg)
	areaId := msg["areaId"].(float64)
	userId := msg["userId"].(float64)
	var plant game.GamePlant
	where:=map[string]interface{}{"userId": userId,"curGrow":"grow4","areaId":areaId}
	if err:=gameDb.Where(where).First(&plant).Error;err!=nil{
		//defer panic(err)
		return false,"植物不存在"
	}
	msg["sType"] = plant.SType
	msg["propName"] = plant.PName
	msg["propId"] = plant.PId
	if err:=gameDb.Delete(&plant).Error;err!=nil{
		return false,"收获失败"
	}
	_,err = m.RpcInvoke("User", "addDepot", msg)
	if err!=""{
		return false,err
	}

	//放到收获那边去
	return true,""
}








































